package io.nutz.irtu.gpsserver.module;

import java.util.List;

import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Fail;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.view.RawView;
import org.nutz.mvc.view.ViewWrapper;

import io.nutz.irtu.gpsserver.GpsServer;
import io.nutz.irtu.gpsserver.bean.DevInfo;
import io.nutz.irtu.gpsserver.bean.DevLocMsg;
import io.nutz.irtu.gpsserver.util.WoozTools;

/**
 * GPS服务器的Http API
 * 
 * @author Administrator
 *
 */
@IocBean
@At("/gps")
@Ok("json:full")
@Fail("http:500")
public class GpsModule {

    @Inject
    protected Dao dao;
    
    @Inject
    protected GpsServer gpsServer;

    /**
     * 获取单个设备的信息
     * 
     * @param imei
     *            设备的IMEI
     * @return
     */
    @At("/dev/info/?")
    public NutMap getInfo(String imei) {
        DevInfo dev = dao.fetch(DevInfo.class, Cnd.where("imei", "=", imei));
        if (dev == null) {
            return new NutMap("ok", false).setv("msg", "no_such_dev");
        }
        DevLocMsg loc = dao.fetch(DevLocMsg.class, Cnd.where("imei", "=", imei).desc("devtime"));
        dev.setLoc(loc);
        return new NutMap("ok", true).setv("data", dev);
    }

    /**
     * 获取设备的最后状态
     * 
     * @param imei
     *            设备的IMEI
     * @return
     */
    @At("/dev/loc/?")
    public NutMap getLoc(String imei) {
        DevInfo dev = dao.fetch(DevInfo.class, Cnd.where("imei", "=", imei));
        if (dev == null) {
            return new NutMap("msg", "no_such_dev");
        }
        DevLocMsg loc = dao.fetch(DevLocMsg.class, Cnd.where("imei", "=", imei).desc("devtime"));
        return new NutMap("ok", true).setv("data", loc);
    }

    /**
     * 获取设备的轨迹数据
     * 
     * @param imei
     *            设备的IMEI
     * @return
     */
    @At("/dev/locs/?")
    public Object getLocs(String imei, long from, long to, boolean mpmap) {
        DevInfo dev = dao.fetch(DevInfo.class, Cnd.where("imei", "=", imei));
        if (dev == null) {
            return new NutMap("msg", "no_such_dev");
        }
        long t_from = from < 1 ? System.currentTimeMillis() - 3*3600*1000L : from; // 默认取3小时好了
        long t_to = to < 1 ? System.currentTimeMillis() : to;
        if (t_to - t_from > 3*86400*1000L) { // 区间最大取7天
            t_from = t_to - 3*86400*1000L;
        }
        List<DevLocMsg> list = dao.query(DevLocMsg.class, Cnd.where("imei", "=", imei).and("devtime", ">", t_from / 1000).and("devtime", "<", t_to/1000).desc("devtime"));
        if (mpmap) {
            StringBuilder sb = new StringBuilder("[");
            for (DevLocMsg loc : list) {
                double[] tmp = WoozTools.wgs84togcj02(loc.getLng(), loc.getLat());
                sb.append(String.format("{\"longitude\":%.7f,\"latitude\":%.7f},", tmp[0], tmp[1]));
            }
            if (sb.length() > 1) {
                sb.setCharAt(sb.length()-1, ']');
                return new ViewWrapper(new RawView("json"), sb.toString());
            }
            return new String[] {};
        }
        else {
            return new NutMap("ok", true).setv("data", list);
        }
    }
    
    @POST
    @At("/dev/wakeup/?")
    public Object wakeup(String imei) {
        DevInfo dev = dao.fetch(DevInfo.class, Cnd.where("imei", "=", imei));
        if (dev == null) {
            return new NutMap("msg", "no_such_dev");
        }
        String msg = gpsServer.sendMsg(dev.getSessionID(), "rrpc,gps_wakeup\r\n".getBytes());
        if (msg == null) {
            return new NutMap("ok", true);
        }
        else {
            return new NutMap("msg", msg);
        }
    }
}
